package cn.touna.jss.modules.third.tongdun;

import cn.touna.jss.common.properties.disconf.TongDunProperties;
import cn.touna.jss.common.util.*;
import cn.touna.jss.modules.adapter.ApiMapping;
import cn.touna.jss.modules.credit.entity.TongDunConfigEntity;
import cn.touna.jss.modules.custom.tongduncoinfig.TongDunConfigService;
import cn.touna.jss.modules.third.tongdun.entity.TongDunReqDTO;
import cn.touna.jss.modules.third.tongdun.entity.TongDunRequestEntity;
import cn.touna.jss.modules.third.tongdun.util.TongDunUtil;
import cn.touna.risk.api.contraints.facet.First;
import cn.touna.risk.api.domain.Response;
import cn.touna.risk.api.enums.SystemErrorCodeEnum;
import cn.touna.risk.api.exception.ServiceException;
import cn.touna.risk.api.http.HttpUtil;
import cn.touna.risk.api.utils.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 同盾接口
 */

@Service
public class TongDunService {
    private static final Logger logger = LogManager.getLogger(TongDunService.class);
    @Autowired
    private TongDunConfigService tongDunConfigService;
    @Autowired
    private TongDunProperties tongdunproperties;

    /**
     * 同盾根据用户基本信息查询报告ID
     *
     * @param entity
     * @return
     */
    @ApiMapping(value = "TongDun.getAccessReportData",desc = "同盾.获取报告")
    private Response getAccessReportData(TongDunRequestEntity entity) {
        Response response = new Response();
        SortedMap<String, String> arguments = new TreeMap<String, String>();
        try {
            arguments.putAll(ConvertUtil.convertBean2Map(entity));
            arguments.put("partner_code", tongdunproperties.getPartnerCode());
            arguments.put("partner_key", tongdunproperties.getPartnerKey());
            arguments.put("app_name", getKeyByEventId(entity.getEvent_id()).get("appName"));
            arguments.put("id_number", entity.getIdCard());

            logger.info("REQ 【同盾查询报告ID请求入参】 getAccessReportData--> paramMap：{},url:{}", JSON.toJSONString(arguments), tongdunproperties.getAccessTokenReportUrl());
            String result = HttpUtil.getInstance().post(tongdunproperties.getAccessTokenReportUrl(), arguments);
            logger.info("RSP 【同盾查询报告ID返回结果】 getAccessReportData--> result：{}", result);
            JSONObject rsultObject = JSONUtil.getJSONObject(result);
            boolean success = rsultObject.getBoolean("success");
            if (!success) {
                String errorMsg = rsultObject.getString("reason_desc");
                return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, errorMsg);
            }
            return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC, result);
        } catch (Exception e) {
            logger.error("调用【同盾查询报告ID】异常,getAccessReportData--> paramMap：{}", JSON.toJSON(arguments), e);
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
        }
    }

    /**
     * 同盾贷前报告
     *
     * @param entity
     * @return
     */
    @ApiMapping(value = "TongDun.queryReportData",desc = "同盾.同盾贷前报告")
    public Response queryReportData(TongDunRequestEntity entity) {
        Response response = new Response();
        SortedMap<String, String> arguments = new TreeMap<String, String>();
        try {
            Response validResponse = ValidUtil.valid(entity, First.class);
            if (validResponse != null)
                return validResponse;
            Response accessReportData = getAccessReportData(entity);
            if (accessReportData.checkIfFail()) {
                return accessReportData;
            }
            JSONObject jsonObject = JSONUtil.getJSONObject(accessReportData.getData().toString());
            entity.setReport_id((String) jsonObject.get("report_id"));
            arguments.putAll(ConvertUtil.convertBean2Map(entity));
            arguments.put("partner_code", tongdunproperties.getPartnerCode());
            arguments.put("partner_key", tongdunproperties.getPartnerKey());
            arguments.put("app_name", getKeyByEventId(entity.getEvent_id()).get("appName"));

            logger.info("REQ 【同盾贷前报告请求入参】 queryReportData--> paramMap：{},url:{}", JSON.toJSONString(arguments), tongdunproperties.getQueryReportUrl());
            String result = HttpUtil.getInstance().get(tongdunproperties.getQueryReportUrl(), arguments);
            logger.info("REQ 【同盾贷前报告返回结果】 queryReportData--> result：{}", result);
            JSONObject rsultObject = JSONUtil.getJSONObject(result);
            boolean success = rsultObject.getBoolean("success");
            if (!success) {
                String errorMsg = rsultObject.getString("reason_desc");
                return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, errorMsg);
            }
            return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC, result);
        } catch (Exception e) {
            logger.error("调用【同盾贷前报告】异常,queryReportData--> paramMap：{}", JSON.toJSON(arguments), e);
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
        }
    }

    /**
     * 从Redis中获取同盾配置信息
     * @param entity
     * @return
     */
    private TongDunConfigEntity getTongDunConfigEntity(TongDunRequestEntity entity) {
        return tongDunConfigService.getTongDunConfigEntity(entity.getProductType(), entity.getPlatform(), entity.getEventType());
    }

    /**
     * 同盾决策引擎,不需要传递EventID
     * @param entity
     * @return
     */
    @ApiMapping(value = "TongDun.queryDecisionEngineV2",desc = "同盾.同盾决策引擎v2")
    public Response queryDecisionEngineV2(TongDunRequestEntity entity) {
        String eventId = entity.getEvent_id();
        if(StringUtils.isBlank(eventId)){
            entity.setEvent_id(this.getTongDunConfigEntity(entity).getEventId());
        }
        return this.queryDecisionEngine(entity);
    }

    /**
     * 同盾决策引擎
     *
     * @param entity
     * @return
     */
    @ApiMapping(value = "TongDun.queryDecisionEngine",desc = "同盾.同盾决策引擎")
    public Response queryDecisionEngine(TongDunRequestEntity entity) {
        String eventId = entity.getEvent_id();
        if(StringUtils.isBlank(eventId)){
            TongDunConfigEntity configEntity = this.getTongDunConfigEntity(entity);
            if(null != configEntity){
                entity.setEvent_id(configEntity.getEventId());
            }
        }
        Response response = new Response();
        Map<String, Object> arguments = new HashMap();
        try {
            arguments.put("partner_code", tongdunproperties.getPartnerCode());
            arguments.put("partner_key", tongdunproperties.getPartnerKey());
            arguments.put("secret_key", getKeyByEventId(entity.getEvent_id()).get("secretKey"));
            arguments.put("token_id", entity.getToken_id());
            arguments.put("black_box", entity.getBlack_box());
            arguments.put("event_id", entity.getEvent_id());// 此处填写策略集上的事件标识
            arguments.put("account_login", entity.getName());
            arguments.put("id_number", entity.getIdCard());
            arguments.put("account_name", entity.getName());
            arguments.put("account_mobile", entity.getMobile());
            arguments.put("ip_address", entity.getIp_address());
            //邮箱
            arguments.put("account_email",entity.getAccountEmail());
            //联系⼈1 姓名
            arguments.put("contact1_name",entity.getContact1_name());
            //联系⼈1电话
            arguments.put("contact1_mobile",entity.getContact1_mobile());
            //联系 2 姓名
            arguments.put("contact2_name",entity.getContact2_name());
            //联系 2 电话
            arguments.put("contact2_mobile",entity.getContact2_mobile());
            //居住地址
            arguments.put("contact_address",entity.getContact_address());
            //工作单位名称
            arguments.put("organization",entity.getCompany_name());
            //单位电话
            arguments.put("work_phone",entity.getWork_phone());
            //职业
            arguments.put("career",entity.getCareer());
            //工作地址
            arguments.put("organization_address",entity.getCompany_address());

            arguments.put("ext_account_email", entity.getAccountEmail());
            arguments.put("ext_account_mobile", entity.getAccountMobile());
            arguments.put("ext_account_mobile2", entity.getAccountMobile2());
            arguments.put("resp_detail_type", "device,geoip,attribution");
            String url = tongdunproperties.getQueryDecisionEngine();
            logger.info("REQ 【同盾决策引擎请求入参】 queryDecisionEngine--> paramMap：{},url:{}", JSON.toJSONString(arguments), url);
            String result = FraudApiInvoker.invoke(arguments, url);
            logger.info("RSP 【同盾决策引擎返回结果】 queryDecisionEngine--> result：{}", result);
            JSONObject jsonObject = JSONUtil.getJSONObject(result);
            if (null != jsonObject) {
                Boolean dataResult = jsonObject.getBoolean("success");
                if (dataResult == null || !dataResult) {

                    String errorMsg = jsonObject.getString("reason_code");
                    return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_FAIL.getErrorCode(), errorMsg);
                }
            }
            Response ruleReponse = ruleDetail(jsonObject.getString("seq_id"));
            JSONObject ruleJson =  (JSONObject)ruleReponse.getData();
            jsonObject.put("rules",ruleJson.getJSONArray("rules"));
            return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC, jsonObject);
        } catch (Exception e) {
            logger.error("调用【同盾决策引擎】异常,queryReportData--> paramMap：{}", JSON.toJSON(arguments), e);
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
        }
    }

    @ApiMapping(value = "TongDun.queryTDScore",desc = "同盾.小微贷分数")
    public Response  queryTDScore(@Valid TongDunReqDTO dto){
//        Response validResponse = ValidUtil.valid(dto);
//        if (validResponse != null)
//            return validResponse;

        Response response = new Response();
        Map<String, String> urlparms = new HashMap();
        Map<String, String> headparms = new HashMap();
        Map<String, String> arguments = new HashMap();
        headparms.put("Content-Type","application/x-www-form-urlencoded");
        arguments.put("biz_code",tongdunproperties.getBizCode());
        arguments.put("account_mobile",dto.getMobile());
        arguments.put("id_number",dto.getIdCard());
        urlparms.put("partner_code",tongdunproperties.getPartnerCode());
        urlparms.put("partner_key",tongdunproperties.getPartnerKey());
        urlparms.put("app_name",tongdunproperties.getAppName());
        String url=tongdunproperties.getQueryTDScore();
        String post = null;
        try {
             post = HttpUtil.getInstance().post(url, urlparms,headparms,arguments);
            JSONObject jsonObject = JSONUtil.getJSONObject(post);
             if(jsonObject.getBoolean("success")&&jsonObject.get("reason_code")==null){

                 return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC, jsonObject);
             }
            return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_FAIL.getErrorCode(), post);
        } catch (Exception e) {
            logger.error("调用【同盾.小微贷分数】异常,queryReportData--> e：{}", e);
            return response.fail(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_FAIL.getErrorCode(), SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_FAIL.getResponseMessage());

        }

    }

    /**
     * 命中规则详情查询
     *
     * @param seqId 事件id
     * @return
     */
    @ApiMapping(value = "TongDun.ruleDetail",desc = "同盾.命中规则详情查询")
    public Response ruleDetail(String seqId) {
        Response response = new Response();
        logger.info("REQ 【同盾命中规则请求入参】 ruleDetail--> seqId：{}", seqId);
        try {
            if (CommonUtils.isEmpty(seqId)) {
                response.fail();
                response.setCode("事件id不能为空");
                response.setCode(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_FAIL.getErrorCode());
                return response;
            }
            StringBuffer sb = new StringBuffer();
            sb.append(tongdunproperties.getRuleUrl() + "?");
            sb.append("partner_code=" + tongdunproperties.getPartnerCode() + "&");
            sb.append("partner_key=" + tongdunproperties.getPartnerKey() + "&");
            sb.append("sequenceId=" + seqId);
            logger.info("REQ 【同盾命中规则】 ruleDetail--> 请求url以及参数：{}", sb.toString());
            JSONObject result = HttpClientUtils.httpGet(sb.toString());
            logger.info("REQ 【同盾命中规则】 ruleDetail--> 请求返回结果：{}", result);
            String msg = "请求失败";
            if (result != null) {
                msg = (String) result.get("reason_desc");
                boolean isSuccess = (boolean) result.get("success");
                if (isSuccess) {
                    return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC, result);
                }
            }
            response.setMsg(msg);
            response.fail();
            return response;
        } catch (Exception e) {
            logger.error("调用【同盾命中规则查询】异常,queryReportData--> seqId：{},e", seqId, e);
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
        }
    }




    /**
     * 根据事件id获取不同的secretKey,appName
     *
     * @param eventId
     * @return
     * @throws Exception
     */
    private Map<String, String> getKeyByEventId(String eventId) throws Exception {
        Map<String, String> keyMap = new HashMap<>();
        if (StringUtils.isBlank(eventId)) {
            throw new ServiceException(SystemErrorCodeEnum.JSS_PARAM_SECRETKEY_ERROR.getErrorCode(), SystemErrorCodeEnum.JSS_PARAM_SECRETKEY_ERROR.getErrorDesc());
        }

        String appName = TongDunUtil.getSecretKeyType(eventId);
        if (StringUtils.equalsIgnoreCase(JssConstant.IOS_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getIosSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.ANDROID_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getAndroidSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.WEB_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getWebSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.TOUNA_WEB, appName)) {
            keyMap.put("secretKey", tongdunproperties.getTounaWebSecretKey());
            keyMap.put("appName", appName);
        }
        //------卡牛----------------
        if (StringUtils.equalsIgnoreCase(JssConstant.KANIU_WEB_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getCarniuWebSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.KANIU_ANDROID_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getCarniuAndroidSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.KANIU_IOS_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getCarniuIosSecretKey());
            keyMap.put("appName", appName);
        }

        //------华润----------------
        if (StringUtils.equalsIgnoreCase(JssConstant.HUARUN_WEB_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getHuarunWebSecretKey());
            keyMap.put("appName", appName);
        }

        if (StringUtils.equalsIgnoreCase(JssConstant.HUARUN_ANDROID_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getHuarunAndroidSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.HUARUN_IOS_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getHuarunIosSecretKey());
            keyMap.put("appName", appName);
        }
        //------爱奇艺----------------
        if (StringUtils.equalsIgnoreCase(JssConstant.IQIYI_WEB_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getIqiyiWebSecretKey());
            keyMap.put("appName", appName);
        }

        if (StringUtils.equalsIgnoreCase(JssConstant.IQIYI_ANDROID_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getIqiyiAndroidSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.IQIYI_IOS_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getIqiyiIosSecretKey());
            keyMap.put("appName", appName);
        }
        //------浩天----------------
        if (StringUtils.equalsIgnoreCase(JssConstant.HAOTIAN_WEB_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getHaotianWebSecretKey());
            keyMap.put("appName", appName);
        }

        if (StringUtils.equalsIgnoreCase(JssConstant.HAOTIAN_ANDROID_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getHaotianAndroidSecretKey());
            keyMap.put("appName", appName);
        }
        if (StringUtils.equalsIgnoreCase(JssConstant.HAOTIAN_IOS_TYPE, appName)) {
            keyMap.put("secretKey", tongdunproperties.getHaotianIosSecretKey());
            keyMap.put("appName", appName);
        }
        return keyMap;
    }


    /**
     * 同盾多头
     *
     * @param entity
     * @return
     */
    @ApiMapping(value = "TongDun.zhcnRuleDetail",desc = "同盾.同盾多头")
    public Response zhcnRuleDetail(TongDunRequestEntity entity) {
        Response response = new Response<>();
        logger.info("REQ 【同盾多头请求入参】 zhcnRuleDetail--> entity：{}", entity);
        try {
            Response validResponse = ValidUtil.valid(entity, First.class);
            if (validResponse != null)
                return validResponse;

            response = queryDecisionEngine(entity);
            logger.info("【查询同盾决策引擎返回】，result:{}", response);
            if (response.checkIfFail() || null == response.getData()) {
                return response;
            }
            JSONObject jsonObject = JSONUtil.getJSONObject(response.getData().toString());
            String seqId = (String) jsonObject.get("seq_id");
            logger.info("RSP 调用【同盾多头规则-zhcnRuleDetail】 seqId:{}", seqId);
            if (CommonUtils.isEmpty(seqId)) {
                response.fail();
                response.setCode("事件id不能为空");
                response.setCode(SystemErrorCodeEnum.JSS_EXTSYSTEM_RESP_FAIL.getErrorCode());
                return response;
            }
            StringBuffer sb = new StringBuffer();
            sb.append(tongdunproperties.getZhcnRuleUrl() + "?");
            sb.append("partner_code=" + tongdunproperties.getPartnerCode() + "&");
            sb.append("partner_key=" + tongdunproperties.getPartnerKey() + "&");
            sb.append("sequenceId=" + seqId);
            logger.info("REQ 【同盾多头规则】 zhcnRuleDetail--> 请求url以及参数：{}", sb.toString());
            JSONObject result = HttpClientUtils.httpGet(sb.toString());
            logger.info("REQ 【同盾多头规则】 zhcnRuleDetail--> 请求返回结果：{}", result);
            String msg = "请求失败";
            if (result != null && result.getString("success").equals("true")) {
                msg = (String) result.get("reason_desc");
                JSONArray jsonArray = handleRule(result);
                response.setMsg(msg);
                return response.success(SystemErrorCodeEnum.SYSTEM_REQUEST_SUCC, jsonArray);
            }
            response.setMsg(msg);
            response.fail();
            return response;
        } catch (Exception e) {
            logger.error("调用【同盾多头规则查询】异常,zhcnRuleDetail--> ,e", e);
            return response.fail(SystemErrorCodeEnum.JSS_CALL_EXTSYSTEM_ERROR, e.getMessage());
        }
    }


    private JSONArray handleRule(JSONObject result) {
        try {
            JSONArray array = new JSONArray();
            JSONArray strategyList = result.getJSONArray(JssConstant.STRATEGYLIST);
            for (int i = 0; i < strategyList.size(); i++) {
                JSONObject json = (JSONObject) strategyList.get(i);
                JSONArray ruleList = json.getJSONArray(JssConstant.RULELIST);
                for (int j = 0; j < ruleList.size(); j++) {
                    JSONObject rule = (JSONObject) ruleList.get(j);
                    String ruleName = rule.getString(JssConstant.RULENAME);
                    if (JssConstant.RULE_MATCH_NAMES.contains(ruleName)) {
                        JSONArray ruleInfo = rule.getJSONArray(JssConstant.RULEINFO);
                        JSONObject ruleMsg = (JSONObject) ruleInfo.get(0);
                        int number = ruleMsg.getInteger(JssConstant.NUMBER);
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put(JssConstant.RULENAME, ruleName);
                        jsonObject.put(JssConstant.NUMBER, number);
                        array.add(jsonObject);
                    }
                }
            }
            logger.info("array : {}", array);
            return array;
        } catch (Exception e) {
            logger.error("zhcnRuleDetail handleRule exception ", e.getMessage());
        }
        return null;
    }


}
